﻿

#include "sparseMatrix.hpp"

namespace UNAP {
template <typename Cmpt>
inline SparseMatrix<Cmpt>::SparseMatrix()
    : gRows_(0),
      gCols_(0),
      nnz_(0),
      symm_(true),
      ptr_(NULL),
      ind_(NULL),
      val_(NULL) {}

template <typename Cmpt>
inline SparseMatrix<Cmpt>::SparseMatrix(label n, label nnz, bool symm)
    : gRows_(n),
      gCols_(n),
      nnz_(nnz),
      symm_(symm),
      ptr_(NULL),
      ind_(NULL),
      val_(NULL) {}

template <typename Cmpt>
inline SparseMatrix<Cmpt>::SparseMatrix(label n, label nnz, label* ptr,
                                        label* ind, Cmpt* val, bool symm)
    : gRows_(n),
      gCols_(n),
      nnz_(nnz),
      symm_(symm),
      ptr_(ptr),
      ind_(ind),
      val_(val) {}

template <typename Cmpt>
inline SparseMatrix<Cmpt>::SparseMatrix(label r, label c, label nnz, bool symm)
    : gRows_(r),
      gCols_(c),
      nnz_(nnz),
      symm_(symm),
      ptr_(NULL),
      ind_(NULL),
      val_(NULL) {}

template <typename Cmpt>
inline SparseMatrix<Cmpt>::SparseMatrix(label r, label c, label nnz, label* ptr,
                                        label* ind, Cmpt* val, bool symm)
    : gRows_(r),
      gCols_(c),
      nnz_(nnz),
      symm_(symm),
      ptr_(ptr),
      ind_(ind),
      val_(val) {}

template <typename Cmpt>
SparseMatrix<Cmpt>::~SparseMatrix() {
  DELETE_POINTERS(ptr_);
  DELETE_POINTERS(ind_);
  DELETE_POINTERS(val_);
}

template <typename Cmpt>
void SparseMatrix<Cmpt>::free() {
  DELETE_POINTERS(ptr_);
  DELETE_POINTERS(ind_);
  DELETE_POINTERS(val_);
}

template <typename Cmpt>
void SparseMatrix<Cmpt>::print() const {
  POUT << "totalSize: " << size() << std::endl;
  POUT << "totalnnz: " << nnz() << std::endl;
}

template <typename Cmpt>
void SparseMatrix<Cmpt>::reorder(const std::vector<label>& iperm,
                                 const std::vector<label>& perm) {
  std::vector<label> ptr(gRows_ + 1), ind(nnz_);
  std::vector<Cmpt> val(nnz_);
  label nnz = 0;
  for (label i = 0; i < gRows_; i++) {
    label ub = ptr_[iperm[i] + 1];
    for (label j = ptr_[iperm[i]]; j < ub; j++) {
      ind[nnz] = perm[ind_[j]];
      val[nnz++] = val_[j];
    }
    ptr[i + 1] = nnz;
  }

  for (label i = 0; i < gRows_; i++)
    sortIndicesValues(ind.data() + ptr[i], val.data() + ptr[i], label(0),
                      ptr[i + 1] - ptr[i]);
  std::copy(ptr.begin(), ptr.end(), ptr_);
  std::copy(ind.begin(), ind.end(), ind_);
  std::copy(val.begin(), val.end(), val_);
}

template class SparseMatrix<scalar>;
template class SparseMatrix<char>;
template class SparseMatrix<std::complex<scalar> >;
}  // namespace UNAP
